iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Modern Web

Phoenix 1.7 完全教學系列 第 19

19 刪除與 link component

  • 分享至 

  • xImage
  •  

Link component

大部分的網頁框架都有額外的 helper 來幫助我們產生複雜的 <a> (anchor tag),Phoenix 也不例外。
目前我們使用的 <a> 都是用在預設的 GET 要求,所以我們不需要帶入額外的東西,也沒有其他安全疑慮,但是這一次我們要使用 <a> 來產生 DELETE 要求,所以最好是使用 Phoenix 提供的 <.link> component 代替。

Link component 有許多的使用方法,在 Controller-View 的範圍裡,都是使用 href attribute 來加上目標路徑 (其他跳轉選項會在後面的 LiveView 章節介紹)。

取代 <a> tag 最常見的 GET 寫法:

<.link href={~p"/notes/new""}>到新筆記頁面</.link>

這次刪除需要的是 DELETE 要求,所以我們要加上 method attribute:

<.link href={~p"/notes/#{note}"} method="delete">刪除</.link>

另外 Phoenix 也提供了 data-confirm attribute 來幫助我們加上確認視窗:

<.link href={~p"/notes/#{note}"} method="delete" data-confirm="確定要刪除?">
  刪除
</.link>

把刪除按鈕加到 index.heex.html 中:

<ul class="flex flex-col gap-4">
  <li
    :for={note <- @notes}
    class="flex justify-between bg-amber-50 p-4 rounded-lg font-bold border-2 border-amber-300"
  >
    <%= note.content %>
    <div>
      <a href={~p"/notes/#{note}/edit"} class="text-amber-800">編輯</a>
      <.link
        href={~p"/notes/#{note}"}
        class="text-amber-800"
        method="delete"
        data-confirm="確定要刪除?"
      >
        刪除
      </.link>
    </div>
  </li>
</ul>

記得把目前所有的 <a> 都改成 <.link>

刪除 controller 函式

刪除與 create 和 update 相當相似,甚至更簡單,因為沒有資料需要處理,找到目標,刪除即可。

def delete(conn, %{"id" => id}) do
  note = Notes.get_note(id)
  {:ok, _note} = Notes.delete_note(note)

  conn
  |> put_flash(:info, "感激筆記刪除成功")
  |> redirect(to: ~p"/notes")
end

小測驗

替刪除功能加上測試

參考解答

describe "delete note" do
  test "deletes chosen note", %{conn: conn} do
    {:ok, note} = Notes.create_note(%{content: "待刪除的筆記內容"})
    conn = delete(conn, ~p"/notes/#{note}")
    assert redirected_to(conn) == ~p"/notes"

    conn = get(conn, ~p"/notes")
    html = html_response(conn, 200)
    assert html =~ "感激筆記刪除成功"
    refute html =~ "待刪除的筆記內容"
  end
end

上一篇
18 修改功能與共用表格
下一篇
20 Elixir Process
系列文
Phoenix 1.7 完全教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言